package com.budwk.app.sqfwV2.component;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.common.component.DictComponent;
import com.budwk.app.common.config.AppException;
import com.budwk.app.sqfw.component.CommonComponent;
import com.budwk.app.sqfw.component.FromSummaryComponent;
import com.budwk.app.sqfw.constants.CommonConstants;
import com.budwk.app.sqfw.constants.DictConstants;
import com.budwk.app.sqfw.constants.TemplateIdsConstants;
import com.budwk.app.sqfw.enums.DownLoadFileNameEnum;
import com.budwk.app.sqfw.enums.StreetEnum;
import com.budwk.app.sqfw.enums.SupportBusinessTypeEnum;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.services.SqfwFormSummaryService;
import com.budwk.app.sqfwDoc.bo.SqfwExcelForSummaryBO;
import com.budwk.app.sqfwDoc.bo.SqfwExcelJudgeRes;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.BaseExcelParamDTO;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.SqfwExcelCreateCommonBO;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.AbstractCustomerPdfCreateField;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.SqfwPdfCreateCommonBO;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.PdfGenerateParam;
import com.budwk.app.sqfwV2.dto.dto.FireSafetyOnDayingRoadPdfDTO;
import com.budwk.app.sqfwV2.dto.dto.centuryCity.SafeCheckTaskParamDataDTO;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.AccommodatePeopleVo;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.DownExcelLedgerReqVo;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.DownFileTypesResVo;
import com.budwk.app.sqfwV2.dto.vo.DocumentDownVo;
import com.budwk.app.sqfwV2.dto.vo.SummaryQueryReqVo;
import com.budwk.app.sqfwV2.enums.DayingRoadFileServiceEnum;
import com.budwk.app.sqfwV2.enums.lanHuaDu.LanHuaDuFileServiceEnum;
import com.budwk.app.sqfwV2.generator.dayingRoadExcel.DayingRoadExcelGenerator;
import com.budwk.app.sqfwV2.generator.dayingRoadPdf.SafetyAllPdfGenerator;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.util.StrUtil;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.budwk.starter.common.result.ResultCode;
import com.budwk.starter.security.utils.SecurityUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.IocBean;

import java.util.*;
import java.util.stream.Collectors;

@IocBean
@Slf4j
public class DayingRoadPdfComponent {

    /**
     * 判断用户是否配置有大营路的安全排查提交权限
     * @return
     */
    public static boolean isDayYingSafeCity(String userId) {
        return CommonComponent.checkUserTemplateInfo(userId, SupportBusinessTypeEnum.SAFE_CHECK.getName(), DictConstants.DAY_SAFE_CODE);
    }

    public static FireSafetyOnDayingRoadPdfDTO getFireSafetyOnDayingRoadPdfDTO(SqfwPdfCreateCommonBO pdfDTO) {
        AbstractCustomerPdfCreateField field = pdfDTO.getAbstractCustomerPdfCreateField();
        if (field == null) {
            throw new AppException("业务异常");
        }
        if (field instanceof FireSafetyOnDayingRoadPdfDTO) {
            return (FireSafetyOnDayingRoadPdfDTO) field;
        }
        throw new AppException("解析参数失败，请联系系统管理员！");
    }

    /**
     * 是否需要生成pdf文档
     * @param type
     *  1:【燃气使用情况】状态中包含了【瓶装液化气】、【瓶装天然气】、【瓶装二甲醚】、三项任意一项时，生成文档。
     *  2:提交就生成
     *
     */
    public static boolean isGeneratePdf(String type, SqfwPdfCreateCommonBO pdfDTO) {
        log.info("DaYingLuPdfComponent pdfCreateConditionCheck start param: {}", JSONObject.toJSONString(pdfDTO));
        if ("2".equals(type)) {
            return true;
        }
        // ○【燃气使用情况】状态中包含了【瓶装液化气】、【瓶装天然气】、【瓶装二甲醚】、三项任意一项时，生成文档。
        if ("1".equals(type)) {
            FireSafetyOnDayingRoadPdfDTO roadPdfDTO = getFireSafetyOnDayingRoadPdfDTO(pdfDTO);
            // 检查 【用火用电情况】状态中包含了【瓶装液化气】、【瓶装天然气】、【瓶装二甲醚】三项任意一项时，生成文档。
            String fireAndElectricityUsage = roadPdfDTO.getFireAndElectricityUsage();
            if (StringUtils.isEmpty(fireAndElectricityUsage)) {
                return false;
            }
            // 获取【瓶装液化气】、【瓶装天然气】、【瓶装二甲醚】编码
            long count = DictComponent.listFireGasCode().stream().filter(fireAndElectricityUsage::contains).count();
            log.info("BottleGasSafetyPdfGenerator pdfCreateConditionCheck end count res: {}", count);
            return count > 0;
        }
        return false;
    }

    /**
     * 构建巡查人员签名
     */
    public static void buildPeersSign(SqfwPdfCreateCommonBO pdfDTO, FireSafetyOnDayingRoadPdfDTO roadPdfDTO, Map<String, Object> paramMap) {
        SqfwFormSummaryService sqfwFormSummaryService = (SqfwFormSummaryService) NutzIocUtils.getBeanByType(SqfwFormSummaryService.class);
        String signUser = pdfDTO.getBasePdfParamDTO().getCreateUserName();
        if (StringUtils.isNotEmpty(roadPdfDTO.getPeers())) signUser = signUser+ "," + roadPdfDTO.getPeers();
        Map<String, List<String>> userSignatureMap = sqfwFormSummaryService.getUserSignatureMap(signUser, pdfDTO.getBasePdfParamDTO().getUnitId());
        // 含有签名图片的和没有签名图片的
        CommonFormOfficeUtils.addWordUserSignature(paramMap, "peersNoSig", "peersSigs", "peersSig",
                userSignatureMap.get("noSig"), userSignatureMap.get("sig"), 1.0F);
        // 巡查人员签名（以前的a19）
        paramMap.put("checkedUnitLeader", null);
        paramMap.put("checkedUnitLeaderStr", "");
        if (StringUtils.isNotEmpty(roadPdfDTO.getCheckedUnitLeader())) {
            paramMap.put("checkedUnitLeader", CommonFormOfficeUtils.addWordPicture(roadPdfDTO.getCheckedUnitLeader(), 1.0F));
        } else {
            paramMap.put("checkedUnitLeaderStr", signUser);
        }
    }

    /**
     * 获取FireSafetyOnDayingRoadPdfDTO对象
     * @param pdfDTO 入参
     * @return FireSafetyOnDayingRoadPdfDTO对象
     */
    public static FireSafetyOnDayingRoadPdfDTO getFireSafetyOnDayingRoadPdfDTO(Map<String, Object> paramMap, SqfwPdfCreateCommonBO pdfDTO) {
        AbstractCustomerPdfCreateField field = pdfDTO.getAbstractCustomerPdfCreateField();
        if (field == null) {
            throw new AppException(ResultCode.NULL_DATA_ERROR.getMsg());
        }
        if (field instanceof FireSafetyOnDayingRoadPdfDTO) {
            // 1 获取所有字段
            FireSafetyOnDayingRoadPdfDTO roadPdfDTO = (FireSafetyOnDayingRoadPdfDTO) field;
            String gasDeliveryCompanyName = getDictName(roadPdfDTO.getGasDeliveryCompany(), roadPdfDTO.getGasDeliveryCompanyName());
            String mainBusinessScopeName = getDictName(roadPdfDTO.getMainBusinessScope(), roadPdfDTO.getMainBusinessScopeName());
            String buildingTypeName = getDictName(roadPdfDTO.getBuildingType(), roadPdfDTO.getBuildingTypeName());
            paramMap.put("gasDeliveryCompanyName", gasDeliveryCompanyName); // 送气公司
            paramMap.put("mainBusinessScopeName", mainBusinessScopeName); // 主要经营类型
            paramMap.put("buildingTypeName", buildingTypeName); // 建筑类型
            paramMap.put("inspectionDate", LocalDateTimeUtil.format(roadPdfDTO.getInspectionDate(), DatePattern.NORM_DATE_PATTERN));
            paramMap.put("whetherStapleFood", roadPdfDTO.getWhetherStapleFood());
            roadPdfDTO.setGasDeliveryCompanyName(gasDeliveryCompanyName)
                    .setMainBusinessScopeName(mainBusinessScopeName)
                    .setBuildingTypeName(buildingTypeName)
                    .setCompetentDepartmentName(getDictName(roadPdfDTO.getCompetentDepartment(), roadPdfDTO.getCompetentDepartmentName()));
            paramMap.put("competentDepartmentName", roadPdfDTO.getCompetentDepartmentName());
            return roadPdfDTO;
        }
        throw new AppException(ResultCode.NULL_DATA_ERROR.getMsg());
    }

    public static String getDictName(String dictCode, String value) {
        if (StringUtils.isNotBlank(value)) {
            return value;
        }
        if (StringUtils.isEmpty(dictCode)) {
            return StringUtils.EMPTY;
        }
        SysDictService sysDictService = NutzIocUtils.getBean(SysDictService.class);
        Sys_dict dict = sysDictService.fetch(Cnd.where(Sys_dict::getCode, "=", dictCode));
        if (dict == null) {
            return StringUtils.EMPTY;
        }
        return dict.getName();
    }

    /**
     *  解析问题 获取是否
     * @param problem 问题参数
     * @return
     */
    public static boolean getProblem(SafeCheckTaskParamDataDTO problem) {
        if (problem == null) {
            return false;
        }
        return problem.getKey().equals(String.valueOf(Boolean.TRUE));
    }

    /**
     * 是否住人
     * @param accommodatePeople
     * @return true: 住人  false: 没有住人
     */
    public static boolean isAccommodatePeople(AccommodatePeopleVo accommodatePeople) {
        if (accommodatePeople == null) {
            return false;
        }
        String residentialType = accommodatePeople.getResidentialType();
        if (StringUtils.isEmpty(residentialType)) {
            return false;
        }
        // 【是否住人】状态不为【否】时，生成该表格。
        return !residentialType.equals(DictConstants.RESIDENTS_FORM_STAY_NOPERSON);
    }

    /**
     * 清除map 获取表数据
     * @param listMap
     * @param excelCreateParam
     * @return
     */
    public static List<Sqfw_formSummary_new> getSummaryList(List<Map<String, Object>> listMap, SqfwExcelCreateCommonBO excelCreateParam) {
        List<SqfwExcelForSummaryBO> dataList = excelCreateParam.getDataList();
        if (dataList == null || dataList.size() == 0){
            return List.of();
        }
        listMap.clear();
        // 排序 按照时间倒序排列
        List<Sqfw_formSummary_new> datas = dataList.stream().map(SqfwExcelForSummaryBO::getSqfwFormSummaryNew)
                .sorted(Comparator.comparing(Sqfw_formSummary_new::getCreateDate).reversed()).collect(Collectors.toList());
        return datas;
    }

    /**
     * 行业领域
     * @param industrySector 字典code
     * @return
     */
    public static List<String> getIndustrySectorStr(String industrySector) {
        if (StringUtils.isEmpty(industrySector)) {
            return Lists.newArrayList();
        }
        Map<String, String> industySectorTypesMap = DictComponent.INDUSTY_SECTOR_TYPES_MAP();
        List<String> names = new ArrayList<>();
        if (StringUtils.isNotEmpty(industrySector)) {
            Arrays.stream(industrySector.split(",")).forEach(code -> {
                String s = industySectorTypesMap.get(code);
                if (StringUtils.isNotEmpty(s)) {
                    names.add(s);
                }
            });
        }
        return names;
    }

    public static SqfwExcelJudgeRes getSqfwExcelJudgeRes(SqfwExcelCreateCommonBO excelCreateParam, DayingRoadExcelGenerator service) {
        SqfwExcelJudgeRes sqfwExcelJudgeRes = new SqfwExcelJudgeRes();
        sqfwExcelJudgeRes.setFileIdentity(excelCreateParam.getExcelCreateConfig().getFileIdentity());
        boolean isDownData = excelCreateParam.getExcelCreateConfig().getOnlyGenerateTemplateFlag(); // 是否下载数据
        for (SqfwExcelForSummaryBO bo : excelCreateParam.getDataList()) {
            FireSafetyOnDayingRoadPdfDTO roadPdfDTO = JSONObject.parseObject(bo.getSqfwFormSummaryNew().getParamData(), FireSafetyOnDayingRoadPdfDTO.class);
            if (service.isGenerateExcel(roadPdfDTO)) {
                isDownData = true;
                break;
            }
        }
        sqfwExcelJudgeRes.setCreateConditionFlag(isDownData);
        return sqfwExcelJudgeRes;
    }

    /**
     * 判断a5是否为重点场所【大型商场、超市、酒店】、【幼儿园、寄宿制学校、社会福利机构】、【医院、诊所、卫生服务站】、【劳动密集型企业、多业态混合经营场所】、【其他重点消防安全场所】
     */
    public static boolean isKeyLocations(FireSafetyOnDayingRoadPdfDTO roadPdfDTO) {
        String mainBusinessScope = roadPdfDTO.getMainBusinessScope();
        if (StringUtils.isNotEmpty(mainBusinessScope)) {
            Optional<String> optional = DictComponent.MAIN_BUSINESS_SCOPE_SAFETY_LIST().stream().filter(code -> code.equals(mainBusinessScope)).findAny();
            return optional.isPresent();
        }
        return false;
    }

    /**
     * 获取填报单位 居委会取值只取街道+社区，当社区=直属时，只显示街道名称
     * @param b
     * @return
     */
    public static String getUnitName(BaseExcelParamDTO b) {
        String community = b.getCommunity(); //社区
        String unitName = StrUtil.formatStr(b.getCounty()) + StrUtil.formatStr(community);
        if (StringUtils.isNotEmpty(community) && CommonConstants.DIRECTLY_UNDER.equals(community)) {
            unitName = StrUtil.formatStr(b.getCounty());
        }
        return unitName;
    }

    public static boolean isDayYingStreet(String unitName) {
        if (StringUtils.isEmpty(unitName)) {
            return false;
        }
        // 判断当前街道是否为大营路 如果是 需要盖章 主要用于盖章用
        return unitName.contains(StreetEnum.DA_YING_LU_STREET.getName());
    }

    public static String getDistrict(String district) {
        if (StringUtils.isEmpty(district)) {
            return StringUtils.EMPTY;
        }
        if (district.equals(CommonConstants.DIRECTLY_UNDER)) {
            return StringUtils.EMPTY;
        }
        return district;
    }

    public static List<Sys_dict> getDicts() {
        SysDictService sysDictService = NutzIocUtils.getBean(SysDictService.class);
        JSONObject result = sysDictService.listDictByCodes(List.of(DictConstants.DAYING_ROAD_EXCEL_COLLECTION));
        List<Sys_dict> vos = result.getJSONArray(DictConstants.DAYING_ROAD_EXCEL_COLLECTION).toJavaList(Sys_dict.class);
        return vos;
    }

    public static DownFileTypesResVo generateDetailFile(List<Sqfw_formSummary_new> formSummarys, SummaryQueryReqVo reqVo) {
        List<DownFileTypesResVo> downFileTypesResVos = generateFiles(formSummarys);
        Optional<DownFileTypesResVo> first = downFileTypesResVos.stream().filter(e -> e.getFileCode().equals(reqVo.getFileCode())).findFirst();
        return first.orElse(null);
    }

    public static List<DownFileTypesResVo> generateFiles(List<Sqfw_formSummary_new> list) {
        List<Sys_dict> vos = getDicts();
        List<DownFileTypesResVo> results = new ArrayList<>();
        // 2 构建数据内容体
        for (Sys_dict vo : vos) {
            getDownFileTypesResVo(results, list, vo);
        }
        // 生成pdf文件
        return generatePdfFiles(results, list);
    }


    private static List<DownFileTypesResVo> generatePdfFiles(List<DownFileTypesResVo> results, List<Sqfw_formSummary_new> list) {
        // 排序(按照修改时间升序)
        List<DownFileTypesResVo> resVos = results.stream().sorted(Comparator.comparing(DownFileTypesResVo::getLocation)).collect(Collectors.toList());
        // 构造模板
        DownExcelLedgerReqVo reqVo = new DownExcelLedgerReqVo();
        reqVo.setDownTemplate(true)
                .setFileCode(DownLoadFileNameEnum.SAFETY_INVESTIGATE_RENOVATE.getCode())
                .setSource(CommonConstants.DAYINGROAD)
                .setFileType(SupportBusinessTypeEnum.SAFETY_CHECK.getName())
                .setDownFileType("pdf");
        DownFileTypesResVo resVo1 = DayingRoadPdfComponent.downTemplate(reqVo);

        // 安全排查表pdf
        DownFileTypesResVo resVo = new DownFileTypesResVo();
        resVo.setFileName(DownLoadFileNameEnum.SAFETY_INVESTIGATE_RENOVATE.getName() + ".pdf").
                setFileCode(DownLoadFileNameEnum.SAFETY_INVESTIGATE_RENOVATE.getCode())
                .setHiveData(list.size() > 0)
                .setLocation(100)
                .setLabel("全部数据|合集|全部表单")
                .setCreatedAt(System.currentTimeMillis())
                .setFileType("pdf")
                .setIds(list.stream().map(Sqfw_formSummary_new::getSqfwFlowId).collect(Collectors.toList()))
                .setFileTemplatePath(resVo1.getFilePath())
                .setPreviewImage(List.of(DayingRoadFileServiceEnum.PDF_PREVIEW));
        resVos.add(resVo);
        if (LanHudDuComponent.isLHDCity(SecurityUtil.getUserId())) {
            // 如果是兰花都街道
            List<DownFileTypesResVo> lhdPdfs = LanHudDuComponent.getAllPdfs(list);
            resVos.addAll(lhdPdfs);
        }
        return resVos;

    }

    public static void getDownFileTypesResVo(List<DownFileTypesResVo> results, List<Sqfw_formSummary_new> list, Sys_dict vo) {
        DownFileTypesResVo resVo = new DownFileTypesResVo();
        DayingRoadFileServiceEnum serviceEnum = DayingRoadFileServiceEnum.getByCode(vo.getCode());
        boolean isGenerate = false;
        List<String> ids = new ArrayList<>();
        for (Sqfw_formSummary_new summary : list) {
            FireSafetyOnDayingRoadPdfDTO roadPdfDTO = JSONObject.parseObject(summary.getParamData(), FireSafetyOnDayingRoadPdfDTO.class);
            if (serviceEnum != null) {
                DayingRoadExcelGenerator service = (DayingRoadExcelGenerator) serviceEnum.getService();
                boolean generateExcel = service.isGenerateExcel(roadPdfDTO);
                if (generateExcel) {
                    isGenerate = true;
                    ids.add(summary.getId());
                }
            }
        }
        // 构造模板
        DownExcelLedgerReqVo reqVo = new DownExcelLedgerReqVo();
        reqVo.setDownTemplate(true)
                .setFileCode(vo.getCode())
                .setSource(CommonConstants.DAYINGROAD)
                .setFileType(SupportBusinessTypeEnum.SAFETY_CHECK.getName())
                .setDownFileType("excel");
        DownFileTypesResVo resVo1 = DayingRoadPdfComponent.downTemplate(reqVo);
        // 组装数据返回
        resVo.setFileCode(vo.getCode())
                .setFileName(vo.getName())
                .setHiveData(isGenerate)
                .setCreatedAt(vo.getCreatedAt())
                .setUpdateAt(vo.getUpdatedAt())
                .setFileType("excel")
                .setIds(ids)
                .setLocation(vo.getLocation())
                .setFileTemplatePath(resVo1.getFilePath());
        if (serviceEnum != null) {
            resVo.setPreviewImage(StringUtils.isNotEmpty(serviceEnum.getPreviewImage()) ? List.of(serviceEnum.getPreviewImage()) : null)
                    .setLabel(serviceEnum.getLabel());
        }
        results.add(resVo);
    }

    public static DownFileTypesResVo downTemplate(DownExcelLedgerReqVo reqVo) {
        String fileCode = reqVo.getFileCode();
        DayingRoadFileServiceEnum serviceEnum = DayingRoadFileServiceEnum.getByCode(fileCode);
        if (serviceEnum != null) {
            reqVo.setIds(List.of(serviceEnum.getTemplateId())).setFileName(serviceEnum.getService().getDownloadFileName());
            return DocumentDownComponent.downExcelTemplateFile(reqVo);
        }
        // 属于pdf模板
        PdfGenerateParam pdfGenerateParam = FromSummaryComponent.initPdfGenerateParam();
        pdfGenerateParam.setAbstractCustomerPdfCreateField(new FireSafetyOnDayingRoadPdfDTO());
        reqVo.setIds(List.of(TemplateIdsConstants.DAYINGROAD_TEMPLATE_ID));

        // 初始化下载参数
        DocumentDownVo documentDownVo = new DocumentDownVo();
        documentDownVo.setReqVo(reqVo).setBasePdfGenerator(new SafetyAllPdfGenerator()).setPdfGenerateParam(pdfGenerateParam)
                .setFileName(DownLoadFileNameEnum.SAFETY_INVESTIGATE_RENOVATE.getName());
        DownFileTypesResVo resVo = DocumentDownComponent.downWordDocTemplate(documentDownVo);
        // 如果是兰花都街道
        if (LanHudDuComponent.isLHDCity(SecurityUtil.getUserId())) {
            LanHuaDuFileServiceEnum serviceEnum1 = LanHuaDuFileServiceEnum.getByCode(reqVo.getFileCode());
            if (serviceEnum1 != null) {
                // 初始化基本参数
                SqfwPdfCreateCommonBO pdfCreateCommonBO = FromSummaryComponent.initPdfSqfwPdfCreateCommonBOParam();
                pdfCreateCommonBO.setAbstractCustomerPdfCreateField(new FireSafetyOnDayingRoadPdfDTO());
                reqVo.setIds(List.of(serviceEnum1.getTemplateId()));

                DocumentDownVo ddv = new DocumentDownVo();
                ddv.setReqVo(reqVo).setBaseTemplatePdfGenerator(serviceEnum1.getService()).setSqfwPdfCreateCommonBO(pdfCreateCommonBO).setFileName(serviceEnum1.getFileName());
                return DocumentDownComponent.downWordDocTemplate(ddv);
            }
        }
        return resVo;
    }
}
